/******************************************************************************************************
 * Author		:	Chester Ragel
 * Date			:	01 - March - 2007
 * Description	:	Helper methods taken from win32 API. This class also contains some structs 
 *					and enums from Win32. Most of them are taken from www.pinvoke.com
 * ****************************************************************************************************/

/*
 *  Context Menu Extention is the legal property of its developer
 *  Chester Ragel <chesterr@gmail.com> - Developer and Maintainer
 *	Sourceforge ID : chesterr
 *	Yahoo ID : chesterr1979 
 *	MSN : chesterr79@hotmail.com
 *	Gmail: chesterr@gmail.com
 *
 * If you want more information, found any bugs or have any doubts you 
 * can mail me or contact me through my yahoo id.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#region Namespace
using System;
using System.Text;
using System.Runtime.InteropServices;
#endregion

namespace Keyrox.Shell {
    internal class Win32 {

        #region Enums

        [Flags]
        internal enum GCSFlags {
            GCS_HELPTEXTA = 1,
            GCS_HELPTEXTW = 5,
            GCS_UNICODE = 4,
            GCS_VALIDATEA = 2,
            GCS_VALIDATEW = 6,
            GCS_VERBA = 0,
            GCS_VERBW = 4
        }

        [Flags]
        internal enum ContextMenuFlag : uint {
            CMF_NORMAL = 0x00000000,
            CMF_DEFAULTONLY = 0x00000001,
            CMF_VERBSONLY = 0x00000002,
            CMF_EXPLORE = 0x00000004,
            CMF_NOVERBS = 0x00000008,
            CMF_CANRENAME = 0x00000010,
            CMF_NODEFAULT = 0x00000020,
            CMF_INCLUDESTATIC = 0x00000040,
            CMF_RESERVED = 0xffff0000
        }

        [Flags]
        internal enum MenuFlags : uint {
            MF_BYCOMMAND = 0,
            MF_BYPOSITION = 0x400,
            MF_CHECKED = 8,
            MF_DISABLED = 2,
            MF_ENABLED = 0,
            MF_GRAYED = 1,
            MF_HILITE = 0x80,
            MF_POPUP = 0x10,
            MF_SEPARATOR = 0x800,
            MF_STRING = 0,
            MF_UNCHECKED = 0
        }

        [Flags]
        internal enum DVASPECT {
            DVASPECT_CONTENT = 1,
            DVASPECT_THUMBNAIL = 2,
            DVASPECT_ICON = 4,
            DVASPECT_DOCPRINT = 8
        }

        internal enum CLIPFORMAT : uint {
            CF_TEXT = 1,
            CF_BITMAP = 2,
            CF_METAFILEPICT = 3,
            CF_SYLK = 4,
            CF_DIF = 5,
            CF_TIFF = 6,
            CF_OEMTEXT = 7,
            CF_DIB = 8,
            CF_PALETTE = 9,
            CF_PENDATA = 10,
            CF_RIFF = 11,
            CF_WAVE = 12,
            CF_UNICODETEXT = 13,
            CF_ENHMETAFILE = 14,
            CF_HDROP = 15,
            CF_LOCALE = 16,
            CF_MAX = 17,

            CF_OWNERDISPLAY = 0x0080,
            CF_DSPTEXT = 0x0081,
            CF_DSPBITMAP = 0x0082,
            CF_DSPMETAFILEPICT = 0x0083,
            CF_DSPENHMETAFILE = 0x008E,

            CF_PRIVATEFIRST = 0x0200,
            CF_PRIVATELAST = 0x02FF,

            CF_GDIOBJFIRST = 0x0300,
            CF_GDIOBJLAST = 0x03FF
        }

        [Flags]
        internal enum TYMED {
            //     No data is being passed.
            TYMED_NULL = 0,
            //     The storage medium is a global memory handle (HGLOBAL). Allocate the global
            //     handle with the GMEM_SHARE flag. If the System.Runtime.Win32Services.ComTypes.STGMEDIUMSystem.Runtime.Win32Services.ComTypes.STGMEDIUM.pUnkForRelease
            //     member is null, the destination process should use GlobalFree to release
            //     the memory.
            TYMED_HGLOBAL = 1,
            //     The storage medium is a disk file identified by a path. If the STGMEDIUMSystem.Runtime.Win32Services.ComTypes.STGMEDIUM.pUnkForRelease
            //     member is null, the destination process should use OpenFile to delete the
            //     file.
            TYMED_FILE = 2,
            //     The storage medium is a stream object identified by an IStream pointer. Use
            //     ISequentialStream::Read to read the data. If the System.Runtime.Win32Services.ComTypes.STGMEDIUMSystem.Runtime.Win32Services.ComTypes.STGMEDIUM.pUnkForRelease
            //     member is not null, the destination process should use IStream::Release to
            //     release the stream component.
            TYMED_ISTREAM = 4,
            //     The storage medium is a storage component identified by an IStorage pointer.
            //     The data is in the streams and storages contained by this IStorage instance.
            //     If the System.Runtime.Win32Services.ComTypes.STGMEDIUMSystem.Runtime.Win32Services.ComTypes.STGMEDIUM.pUnkForRelease
            //     member is not null, the destination process should use IStorage::Release
            //     to release the storage component.
            TYMED_ISTORAGE = 8,
            //     The storage medium is a Graphics Device Interface (GDI) component (HBITMAP).
            //     If the System.Runtime.Win32Services.ComTypes.STGMEDIUMSystem.Runtime.Win32Services.ComTypes.STGMEDIUM.pUnkForRelease
            //     member is null, the destination process should use DeleteObject to delete
            //     the bitmap.
            TYMED_GDI = 16,
            //     The storage medium is a metafile (HMETAFILE). Use the Windows or WIN32 functions
            //     to access the metafile's data. If the System.Runtime.Win32Services.ComTypes.STGMEDIUMSystem.Runtime.Win32Services.ComTypes.STGMEDIUM.pUnkForRelease
            //     member is null, the destination process should use DeleteMetaFile to delete
            //     the bitmap.
            TYMED_MFPICT = 32,
            //     The storage medium is an enhanced metafile. If the System.Runtime.Win32Services.ComTypes.STGMEDIUMSystem.Runtime.Win32Services.ComTypes.STGMEDIUM.pUnkForRelease
            //     member is null, the destination process should use DeleteEnhMetaFile to delete
            //     the bitmap.
            TYMED_ENHMF = 64,
        }

        #endregion

        #region Structs

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        internal struct CMINVOKECOMMANDINFO {
            public int cbSize;
            public uint fMask;
            public uint wnd;
            public int verb;
            [MarshalAs(UnmanagedType.LPStr)]
            public string parameters;
            [MarshalAs(UnmanagedType.LPStr)]
            public string directory;
            public int Show;
            public uint HotKey;
            public uint hIcon;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct FORMATETC {
            public CLIPFORMAT cfFormat;
            public uint ptd;
            public DVASPECT dwAspect;
            public int lindex;
            public TYMED tymed;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct STGMEDIUM {
            public uint tymed;
            public uint hGlobal;
            public uint pUnkForRelease;
        }

        internal struct HMenu {
            public HMenu(IntPtr x) {
                handle = x;
            }
            public IntPtr handle;
        }

        #endregion

        #region Interfaces

        [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("000214e8-0000-0000-c000-000000000046")]
        internal interface IShellExtInit {
            [PreserveSig()]
            int Initialize(IntPtr pidlFolder, IntPtr lpdobj, uint hKeyProgID);
        }

        [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("000214e4-0000-0000-c000-000000000046")]
        internal interface IContextMenu {
            [PreserveSig()]
            int QueryContextMenu(HMenu hmenu, uint iMenu, uint idCmdFirst, int idCmdLast, Win32.ContextMenuFlag uFlags);
            [PreserveSig()]
            void InvokeCommand(ref CMINVOKECOMMANDINFO pici);
            [PreserveSig()]
            void GetCommandString(uint idCmd, uint uFlags, IntPtr pwReserved, IntPtr pszName, uint cchMax);
        }


        [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("0000010e-0000-0000-C000-000000000046")]
        internal interface IDataObject {
            [PreserveSig()]
            int GetData(ref FORMATETC a, ref STGMEDIUM b);
            [PreserveSig()]
            void GetDataHere(int a, ref STGMEDIUM b);
            [PreserveSig()]
            int QueryGetData(int a);
            [PreserveSig()]
            int GetCanonicalFormatEtc(int a, ref int b);
            [PreserveSig()]
            int SetData(int a, int b, int c);
            [PreserveSig()]
            int EnumFormatEtc(uint a, ref Object b);
            [PreserveSig()]
            int DAdvise(int a, uint b, Object c, ref uint d);
            [PreserveSig()]
            int DUnadvise(uint a);
            [PreserveSig()]
            int EnumDAdvise(ref Object a);
        }

        #endregion

        #region Methods

        [DllImport("user32")]
        internal static extern HMenu CreatePopupMenu();
        [DllImport("user32")]
        internal static extern bool AppendMenu(HMenu hmenu, MenuFlags uflags, IntPtr uIDNewItemOrSubmenu, string text);
        [DllImport("user32")]
        internal static extern bool InsertMenu(HMenu hmenu, int position, MenuFlags uflags, IntPtr uIDNewItemOrSubmenu, string text);
        [DllImport("shell32")]
        internal static extern uint DragQueryFile(IntPtr hDrop, uint iFile, [Out] StringBuilder lpszFile, uint cch);
        [DllImport("user32")]
        internal static extern bool SetMenuItemBitmaps(HMenu hmenu, int position, MenuFlags uflags, IntPtr hBitmapUnchecked, IntPtr hBitmapChecked);

        #endregion

    }
}
